﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace Ling.P2P.Provider
{
    /// <summary>
    /// 用于在 P2P 数据接收事件中进行数据传递的对象类型。
    /// </summary>
    public class ReceiveDataEventArgs : EventArgs
    {
        private IPEndPoint _FromEndPoint;
        private P2PMessage? _Message;
        private Socket _skt;

        /// <summary>
        /// 创建一个 ReceiveDataEventArgs 实例。
        /// </summary>
        /// <param name="from"></param>
        /// <param name="d"></param>
        /// <param name="msg"></param>
        public ReceiveDataEventArgs(IPEndPoint from, Socket sket, P2PMessage? msg)
        {
            _FromEndPoint = from;
            _skt = sket;
            _Message = msg;
        }

        /// <summary>
        /// 获取接收到的数据的来源目标主机信息。
        /// </summary>
        public IPEndPoint FromEndPoint
        {
            get { return _FromEndPoint; }
        }

        /// <summary>
        /// 获取与本次接收相关的消息。
        /// </summary>
        public P2PMessage? Message
        {
            get { return _Message; }
        }

        /// <summary>
        /// 获取用于接收数据所需的 socket 对象。
        /// </summary>
        public Socket skt
        {
            get { return _skt; }
        }
    }

    /// <summary>
    /// 用于在 P2P 文件收发事件中进行数据传递的对象类型。
    /// </summary>
    public class ReceiveFileEventArgs : EventArgs
    {
        private IPEndPoint _FromEndPoint;
        private string _FileName;
        private int _StatusCode;

        public ReceiveFileEventArgs(IPEndPoint endIp)
        {
            _FromEndPoint = endIp;
        }

        public IPEndPoint FromEndPoint
        {
            get { return _FromEndPoint; }
        }

        /// <summary>
        /// 当将收到文件传输请求时，该值为被请求传输的文件名。为此吃性设置值后就表过此文件需要存放到的位置（将之置空表示拒绝文件传转请求）；
        /// 文件传输结束后，它就是存储路径。
        /// </summary>
        public string FileName
        {
            get { return _FileName; }
            set 
            { 
                _FileName = value;
                if (!string.IsNullOrEmpty(_FileName))
                    _StatusCode = P2PConstants.SEND_ACCEPT;
                else
                    _StatusCode = -1;
            }
        }

        /// <summary>
        /// 获取或设置一个接收请请的状态码，当指定文件存储路径后会自动置为接受。0 值表示告诉接收程序等待响应。
        /// 其它值参见 P2PConstants 类中的常量值。
        /// </summary>
        public int StatusCode
        {
            get { return _StatusCode; }
            set { _StatusCode = value; }
        }
    }

    /// <summary>
    /// 用于在 P2P 文件收发过程事件中进行数据传北的对象类型。
    /// </summary>
    public class ReceivingFileEventArgs : EventArgs
    {
        private long _TotalLength;
        private long _ReceivedLength;

        /// <summary>
        /// 创建一个 ReceivingFileEventArgs 实例。
        /// </summary>
        /// <param name="tlen"></param>
        /// <param name="rlen"></param>
        public ReceivingFileEventArgs(long tlen, long rlen)
        {
            _TotalLength = tlen;
            _ReceivedLength = rlen;
        }

        /// <summary>
        /// 获取该文件的总字节量。
        /// </summary>
        public long TotalLength
        {
            get { return _TotalLength; }
        }

        /// <summary>
        /// 获取已接收的字节量。
        /// </summary>
        public long ReceivedLength
        {
            get { return _ReceivedLength; }
        }
    }

    /// <summary>
    /// 用于执行 P2PEntry 接收到数据请求时的事件的委托。
    /// </summary>
    /// <param name="sender">引发事件的 P2PEntry 对象。</param>
    /// <param name="e">包含该事件所需的数据信息的对象。</param>
    public delegate void ReceiveEventHandler(TcpP2PEntry sender, ReceiveDataEventArgs e);

    /// <summary>
    /// 用于执行文件传输事件的委托。
    /// </summary>
    /// <param name="sender">引发事件的 P2PEntry 对象。</param>
    /// <param name="e">事件处理所需数据传输对象。</param>
    public delegate void ReceiveFileEventHandler(TcpP2PEntry sender, ReceiveFileEventArgs e);

    /// <summary>
    /// 用于执行在文件传输过程中的事件的委托。
    /// </summary>
    /// <param name="sender">引发事件的 P2PEntry 对象。</param>
    /// <param name="e">事件处理所需数据传输对象。</param>
    public delegate void ReceivingFileEventHandler(TcpP2PEntry sender, ReceivingFileEventArgs e);

    /// <summary>
    /// 用于执行消息发送过程中的回调函数的委托。
    /// </summary>
    /// <param name="Msg">与之关联的消息。</param>
    /// <param name="skt">与之相关的 Socket 对象。</param>
    public delegate void AfterSendMessageHandler(P2PMessage Msg, Socket skt);

    /// <summary>
    /// 用于处理登入状态事件的委托。
    /// </summary>
    /// <param name="sender">引发事件的 P2PEntry 对象。</param>
    /// <param name="skt">连接到该事件的 Socket 对象。</param>
    public delegate void LogInStatusEventHandler(TcpP2PEntry sender, Socket skt);
}
